home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 201-225 / disk_217 / stevie / s_io.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  10KB  |  473 lines

  1. /*
  2.  * s_io() - routines that do screen I/O or effect what we think is
  3.  *          on the screen.
  4.  *
  5.  * By G. R. (Fred) Walter    watmath!watcgl!grwalter 
  6.  */
  7.  
  8. #include "stevie.h"
  9.  
  10. /*
  11.  * screen_ins(row, nlines, total_rows) - insert 'nlines' lines at 'row' 
  12.  *
  13.  * NOTE: this routine assumes it is called with valid arguments.
  14.  */
  15.  
  16. static void
  17. screen_ins(row, nlines, total_rows)
  18.     int             row;
  19.     int             nlines;
  20.     int             total_rows;
  21. {
  22.     if (nlines < 1 || (row + nlines) > total_rows)
  23.     return;
  24.  
  25. #ifndef T_IL_B
  26.     {
  27.     int             i;
  28.  
  29.     for (i = 0; i < nlines; i++) {
  30.         windgoto(row, 0);
  31.         outstr(T_IL);
  32.     }
  33.     }
  34. #else
  35.     windgoto(row, 0);
  36.     outstr(T_IL);
  37.     if (nlines >= 10)
  38.     outchar((char) (nlines / 10 + '0'));
  39.     outchar((char) (nlines % 10 + '0'));
  40.     outstr(T_IL_B);
  41. #endif
  42.  
  43.     /* delete any garbage that may have been shifted to the status line */
  44.     windgoto(total_rows - 1, 0);
  45.     outstr(T_EL);
  46. }
  47.  
  48. /*
  49.  * screen_del(row, nlines, total_rows) - delete 'nlines' lines at 'row' 
  50.  *
  51.  * NOTE: this routine assumes it is called with valid arguments.
  52.  */
  53.  
  54. static void
  55. screen_del(row, nlines, total_rows)
  56.     int             row;
  57.     int             nlines;
  58.     int             total_rows;
  59. {
  60.     if (nlines < 1 || (row + nlines) > total_rows)
  61.     return;
  62.  
  63.     /* delete any garbage that may have been on the status line */
  64.     windgoto(total_rows - 1, 0);
  65.     outstr(T_EL);
  66.  
  67. #ifndef T_DL_B
  68.     {
  69.     int             i;
  70.  
  71.     for (i = 0; i < nlines; i++) {
  72.         windgoto(row, 0);
  73.         outstr(T_DL);    /* delete a line */
  74.     }
  75.     }
  76. #else
  77.     windgoto(row, 0);
  78.     outstr(T_DL);
  79.     if (nlines >= 10)
  80.     outchar((char) (nlines / 10 + '0'));
  81.     outchar((char) (nlines % 10 + '0'));
  82.     outstr(T_DL_B);
  83. #endif
  84. }
  85.  
  86. /*
  87.  * screen_refresh()
  88.  *
  89.  * Based on the current value of Topchar, refresh the contents of the screen
  90.  * and update Botchar.
  91.  */
  92.  
  93. static void
  94. screen_refresh(type)
  95.     int             type;
  96. {
  97.     char           *ptr;
  98.     int             total_rows;
  99.     int             row;
  100.     int             col;
  101.     LINE           *memp;
  102.     LPtr            start;
  103.     bool_t          off_top;
  104.     bool_t          done;    /* if TRUE, we hit the end of the file */
  105.     bool_t          didline;    /* if TRUE, we finished the last line */
  106.     int             lno;    /* number of the line we're doing */
  107.     int             coff;
  108.     int             idx;
  109.     int             i;
  110.     int             j;
  111.  
  112.     if (NumLineSizes <= 0)
  113.     type = NOT_VALID;
  114.  
  115.     if (!RedrawingDisabled)
  116.     outstr(T_CI);
  117.  
  118.     off_top = FALSE;
  119.     idx = 0;
  120.     row = 0;
  121.     total_rows = Rows - 1;
  122.     memp = Topchar->linep;
  123.  
  124.     if ((type == VALID) || (type == VALID_TO_CURSCHAR)) {
  125.     j = -1;
  126.     for (i = 0; i < NumLineSizes; i++) {
  127.         if (LinePointers[i] == memp) {
  128.         j = i;
  129.         break;
  130.         }
  131.         row += LineSizes[i];
  132.     }
  133.     if (j == -1) {
  134.         /* Are we off the top of the screen by one line ? */
  135.         if (memp->next == LinePointers[0]) {
  136.         i = plines(Topchar->linep->s);
  137.         if (i < (total_rows)) {
  138.             off_top = TRUE;
  139.             for (idx = NumLineSizes; idx > 0; idx--) {
  140.             LinePointers[idx] = LinePointers[idx - 1];
  141.             LineSizes[idx] = LineSizes[idx - 1];
  142.             }
  143.             LineSizes[idx] = (char) i;
  144.             if (!RedrawingDisabled)
  145.             screen_ins(0, i, Rows);
  146.         }
  147.         }
  148.         row = 0;
  149.     } else if (j == 0 && type == VALID) {
  150.         if (!RedrawingDisabled)
  151.         outstr(T_CV);
  152.         return;
  153.     } else {
  154.         if (!RedrawingDisabled)
  155.         screen_del(0, row, Rows);
  156.         row = 0;
  157.         for (;;) {
  158.         LineSizes[idx] = LineSizes[j];
  159.         LinePointers[idx] = LinePointers[j];
  160.  
  161.         if (type == VALID_TO_CURSCHAR) {
  162.             if (LinePointers[idx] == Curschar->linep) {
  163.             memp = LinePointers[idx];
  164.             break;
  165.             }
  166.         }
  167.         j++;
  168.         if (j >= NumLineSizes) {
  169.             memp = LinePointers[idx];
  170.             if (memp->next != Fileend->linep) {
  171.             row += LineSizes[idx];
  172.             idx++;
  173.             memp = memp->next;
  174.             }
  175.             break;
  176.         }
  177.         row += LineSizes[idx];
  178.         idx++;
  179.         }
  180.     }
  181.     }
  182.     coff = 0;
  183.     if (P(P_NU)) {
  184.     coff = 8;
  185.     start.linep = memp;
  186.     lno = cntllines(Filemem, &start);
  187.     }
  188.     didline = TRUE;
  189.     done = FALSE;
  190.  
  191.     for (;;) {
  192.     ptr = format_line(memp->s, &col);
  193.     i = 1 + ((col - 1) / Columns);
  194.     if ((row + i) <= total_rows) {
  195.         LinePointers[idx] = memp;
  196.         LineSizes[idx++] = (char) i;
  197.         if (!RedrawingDisabled) {
  198.         windgoto(row, 0);
  199.  
  200.         if (P(P_NU))
  201.             outstr(mkline(lno++));
  202.         outstr(ptr);
  203.  
  204.         j = col + coff;
  205.         col = j % Columns;
  206.         if ((col != 0) || (j == 0)) {
  207. #ifdef T_END_L
  208.             windgoto(row + i - 1, col);
  209.             outstr(T_END_L);
  210. #else
  211.             for (; col < Columns; col++)
  212.             outchar(' ');
  213. #endif
  214.         }
  215.         }
  216.         row += i;
  217.         if (memp->next != Fileend->linep) {
  218.         memp = memp->next;
  219.         } else {
  220.         done = TRUE;
  221.         break;
  222.         }
  223.         if (off_top)
  224.         break;
  225.     } else {
  226.         didline = FALSE;
  227.         break;
  228.     }
  229.     }
  230.  
  231.     /* Do we have to do off the top of the screen processing ? */
  232.     if (off_top && !done) {
  233.     row = 0;
  234.     for (idx = 0; idx <= NumLineSizes && row < total_rows; idx++) {
  235.         row += LineSizes[idx];
  236.     }
  237.  
  238.     idx--;
  239.  
  240.     if (row < total_rows) {
  241.         done = TRUE;
  242.         idx++;
  243.     } else if (row > total_rows) {
  244.         row -= LineSizes[idx];
  245.         didline = FALSE;
  246.         memp = LinePointers[idx];
  247.     } else {
  248.         didline = TRUE;
  249.         memp = LinePointers[idx]->next;
  250.         idx++;
  251.     }
  252.     }
  253.     NumLineSizes = idx;
  254.  
  255.     /*
  256.      * If we didn't hit the end of the file, and we didn't finish the last
  257.      * line we were working on, then the line didn't fit. 
  258.      */
  259.     if (!done && !didline) {
  260.     if (!RedrawingDisabled) {
  261.         /* Clear the rest of the screen. */
  262. #ifdef T_END_D
  263.         windgoto(row, 0);
  264.         outstr(T_END_D);
  265. #else
  266.         screen_del(row, total_rows - row, Rows);
  267.         windgoto(row, 0);
  268. #endif
  269.         /* put '@'s on rows that are part of a line that's too long */
  270.         for (; row < total_rows; row++)
  271.         outstr("@\n\r");
  272.     }
  273.     Botchar->linep = memp;
  274.     } else {
  275.     if (!RedrawingDisabled && !off_top) {
  276.         /* Clear the rest of the screen. */
  277. #ifdef T_END_D
  278.         windgoto(row, 0);
  279.         outstr(T_END_D);
  280. #else
  281.         screen_del(row, total_rows - row, Rows);
  282.         windgoto(row, 0);
  283. #endif
  284.         /* put '~'s on rows that aren't part of the file. */
  285.         for (; row < total_rows; row++)
  286.         outstr("~\n\r");
  287.     }
  288.     if (done)        /* we hit the end of the file */
  289.         *Botchar = *Fileend;
  290.     else
  291.         Botchar->linep = memp;    /* FIX - prev? */
  292.     }
  293.  
  294.     if (!RedrawingDisabled)
  295.     outstr(T_CV);
  296. }
  297.  
  298. /*
  299.  * s_refresh()
  300.  *
  301.  * Based on the current value of Curschar, (if necessary) update Topchar and
  302.  * Botchar and refresh the screen contensts.
  303.  */
  304.  
  305. void
  306. s_refresh(type)
  307.     int             type;
  308. {
  309.     LPtr           *p;
  310.     LPtr           *pp;
  311.     int             i;
  312.     int             nlines;
  313.     int             refreshed;
  314.  
  315.     refreshed = FALSE;
  316.  
  317.     if (bufempty()) {        /* special case - file is empty */
  318.     *Topchar = *Filemem;
  319.     *Curschar = *Filemem;
  320.     screen_refresh(NOT_VALID);
  321.     return;
  322.     }
  323.     if (NumLineSizes < 0) {
  324.     type = NOT_VALID;
  325.     }
  326.     if (type != VALID) {
  327.     screen_refresh(type);
  328.     refreshed = TRUE;
  329.     type = VALID;
  330.     }
  331.     if (LINEOF(Curschar) < LINEOF(Topchar)) {
  332.     nlines = cntllines(Curschar, Topchar);
  333.     /*
  334.      * if the cursor is above the top of the screen, put it at the top of
  335.      * the screen.. 
  336.      */
  337.     *Topchar = *Curschar;
  338.     Topchar->index = 0;
  339.     /*
  340.      * ... and, if we weren't very close to begin with, we scroll so that
  341.      * the line is close to the middle. 
  342.      */
  343.     if (nlines > Rows / 3) {
  344.         p = Topchar;
  345.         for (i = 0; i < Rows / 3; i += plines(p->linep->s)) {
  346.         pp = prevline(p);
  347.         if (pp == NULL)
  348.             break;
  349.         p = pp;
  350.         }
  351.         *Topchar = *p;
  352.     }
  353.     screen_refresh(VALID);
  354.     } else if (LINEOF(Curschar) >= LINEOF(Botchar)) {
  355.     nlines = cntllines(Botchar, Curschar);
  356.     /*
  357.      * If the cursor is off the bottom of the screen, put it at the top
  358.      * of the screen.. ... and back up 
  359.      */
  360.     if (nlines > Rows / 3) {
  361.         p = Curschar;
  362.         for (i = 0; i < (2 * Rows) / 3; i += plines(p->linep->s)) {
  363.         pp = prevline(p);
  364.         if (pp == NULL)
  365.             break;
  366.         p = pp;
  367.         }
  368.         *Topchar = *p;
  369.     } else {
  370.         scrollup(nlines);
  371.     }
  372.     screen_refresh(VALID);
  373.     } else if (refreshed == FALSE) {
  374.     screen_refresh(type);
  375.     }
  376.     /* Check if we are below Botchar (this can occur). */
  377.     if (LINEOF(Curschar) == LINEOF(Botchar)) {
  378.     pp = nextline(Topchar);
  379.     if (pp != NULL) {
  380.         Topchar->linep = pp->linep;
  381.         screen_refresh(VALID);
  382.     }
  383.     } else if (LINEOF(Curschar) > LINEOF(Botchar)) {
  384.     nlines = cntllines(Botchar, Curschar);
  385.     /*
  386.      * If the cursor is off the bottom of the screen, put it at the top
  387.      * of the screen.. ... and back up 
  388.      */
  389.     if (nlines > Rows / 3) {
  390.         p = Curschar;
  391.         for (i = 0; i < (2 * Rows) / 3; i += plines(p->linep->s)) {
  392.         pp = prevline(p);
  393.         if (pp == NULL)
  394.             break;
  395.         p = pp;
  396.         }
  397.         *Topchar = *p;
  398.     } else {
  399.         scrollup(nlines);
  400.     }
  401.     screen_refresh(VALID);
  402.     }
  403. }
  404.  
  405. /*
  406.  * s_clear() - clear the screen and mark the stored information as invalid.
  407.  */
  408. void
  409. s_clear()
  410. {
  411.     outstr(T_ED);        /* clear the display */
  412.     S_NOT_VALID;
  413. }
  414.  
  415. /*
  416.  * Update_Botchar()
  417.  *
  418.  * Based on the current value of Topchar update Botchar.
  419.  */
  420.  
  421. void
  422. Update_Botchar()
  423. {
  424.     int             row;
  425.     LINE           *memp;
  426.     int             total_rows;
  427.     int             i;
  428.  
  429.     row = 0;
  430.     total_rows = Rows - 1;
  431.     memp = Topchar->linep;
  432.  
  433.     for (;;) {
  434.     i = plines(memp->s);
  435.     if ((row + i) <= total_rows) {
  436.         row += i;
  437.         memp = memp->next;
  438.         if (memp == Fileend->linep)
  439.         break;
  440.     } else {
  441.         break;
  442.     }
  443.     }
  444.     Botchar->linep = memp;
  445.  
  446.     MustUpdateBotchar = FALSE;
  447. }
  448.  
  449. #ifdef DONTINCLUDEANYMORE
  450. /*
  451.  * NotValidFromCurschar()
  452.  *
  453.  * Mark the lines in NumLinePointers and NumLineSizes from Curschar on as
  454.  * not valid.
  455.  */
  456.  
  457. void
  458. NotValidFromCurschar()
  459. {
  460.     register int    idx;
  461.     register unsigned long num;
  462.  
  463.     S_VALID_TO_CURSCHAR;
  464.  
  465.     num = LINEOF(Curschar);
  466.     for (idx = 0; idx < NumLineSizes; idx++) {
  467.     if (LinePointers[idx]->num >= num)
  468.         break;
  469.     }
  470.     NumLineSizes = idx;
  471. }
  472. #endif
  473.